home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekikoh Dennoh Club 5
/
Gekikoh Dennoh Club Vol. 5 (Japan).7z
/
Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin
/
internet
/
webx
/
rbget020.lzh
/
WebCache
/
WebCache.c
next >
Wrap
C/C++ Source or Header
|
1998-09-27
|
11KB
|
477 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../FuncUrl/FuncUrl.h"
#ifdef WEBXPRESSION
#include "../WebXpression.h"
#endif
#ifdef ROBOGET
#include "../RoboGet.h"
#endif
#ifdef WEBCM
#include "../WebCM.h"
#endif
/* URL é╞âeâôâ|âëâèâtâ@âCâïû╝é╠æ╬ë₧ì\æóæ╠ */
typedef struct _temptable {
struct _temptable *next;/* ò╨ò√îⁿâèâXâg */
char hash; /* ânâbâVâàÆl */
char type; /* Content-Type */
unsigned int number; /* âeâôâ|âëâèâtâ@âCâïû╝üié╠ÉöÆlòöüj */
unsigned int length; /* âtâ@âCâïâTâCâY */
short year; /* 0...32767 */
char mon; /* 1...12 */
char day; /* 1...31 */
char hour; /* 0...23 */
char min; /* 0...59 */
char sec; /* 0...59 */
char access; /* âAâNâZâXâtâëâO */
char url[0]; /* urlüiGCC é╔ê╦æ╢é╡é╜ò\ïLé┼éáéΘé▒é╞é╔Æìê╙üj */
} TEMPTABLE;
static char *content_type_str[]=
{"text/html", "text/plain", "text/plain",
"image/gif", "image/jpeg", "image/ping", "image/bmp",
"application/zip", "application/lzh", "application/gzip",
"application/pdf",
"application/octet-stream", "unknown/unknown"};
static char *ext_type_str[]=
{"HTM", "TXT", "DOC",
"GIF", "JPG", "PNG", "BMP",
"ZIP", "LZH", "TGZ",
"PDF",
"DAT", "DAT"};
/* WCExist é╠ò╘éΦÆl */
enum {
WC_NON = 0, /* âLâââbâVâàé╔æ╢ì▌é╡é╚éó */
WC_INCACHE, /* üV é╔æ╢ì▌é╡üAïNô«îπÅëé▀é─é╠âAâNâZâX */
WC_INCACHE2, /* üV é╔æ╢ì▌é╡üAïNô«îπéPë±ê╚ÅπâAâNâZâXé╡é─éóéΘ */
WC_LOCAL /* âìü[âJâïâtâ@âCâïé╞é╡é─æ╢ì▌é╖éΘüifile:// Ä₧üj */
};
TEMPTABLE *tt_top = NULL, *tt_end = NULL;
unsigned int cache_sum = 0; /* î╗ì▌âLâââbâVâàé╡é─éóéΘâtâ@âCâïÉö */
unsigned int abs_max = 0; /* Cxxxxxxx é╠ì┼æσÆl+1 */
unsigned int abs_min = -1; /* Cxxxxxxx é╠ì┼żÆl */
char cachedir[256]; /* è┬ï½ò╧Éö WEBCACHE */
char cache_changed; /* âLâââbâVâàé╠ôαùeé≡éPë±é┼éαò╧ìXé╡é╜é⌐üH */
/* url é⌐éτânâbâVâàÆlé≡ïüé▀éΘ */
static char Url2Hash (char *url)
{
char c = 0, t, *p = url;
while (t = *p++) {
if ((t >= 'A') && (t <= 'Z'))
t |= 0x20;
c ^= t;
}
return (c);
}
/* âmü[âhùpé╠âüâéâèé≡èmò█ */
static TEMPTABLE *TTAlloc (char *url)
{
return (malloc (sizeof (TEMPTABLE) + strlen (url) + 1));
}
/* âmü[âhé≡âèâXâgé╠ûûö÷é╔éPé┬Æ╟ë┴ */
static void TTInsert (TEMPTABLE * tt)
{
if (tt_end == NULL) {
/* âmü[âhé¬éPé┬éαé╚éóÅΩìç */
tt_top = tt;
} else {
tt_end->next = tt;
}
tt_end = tt;
tt->next = NULL;
cache_changed = !0;
}
/* âmü[âhé≡éPé┬ìφÅ£ */
static void TTDelete (TEMPTABLE * tt, TEMPTABLE * tt_b)
{
if (tt->next == NULL) {
if (tt == tt_top) {
/* éPé┬é╡é⌐é╚éóâmü[âhé≡ìφÅ£é╖éΘÅΩìç */
tt_top = NULL;
tt_end = NULL;
} else {
/* ûûö÷é╠âmü[âhé╠ÅΩìç */
tt_end = tt_b;
tt_end->next = NULL;
}
} else {
if (tt == tt_top) {
/* ɵô¬é╠âmü[âhé≡ìφÅ£é╖éΘÅΩìç */
tt_top = tt->next;
} else {
tt_b->next = tt->next;
}
}
free (tt);
cache_changed = !0;
}
int WCInit (void)
{
FILE *fp;
char *t;
char temp_str[1024];
t = getenv ("WEBCACHE");
if (t)
strcpy (cachedir, t);
else
*cachedir = '\0';
strcpy (temp_str, cachedir);
strcat (temp_str, "WebCache.env");
if ((fp = fopen (temp_str, "r")) != NULL) {
while (fgets (temp_str, 1024, fp) != NULL) {
int year, mon, day, hour, min, sec;
int number, length;
char url[256], ext[4], type[39];
TEMPTABLE *tt;
int i;
sscanf (temp_str, "C%7d.%s %4d/%2d/%2d %2d:%2d:%2d %d %s %s\n",
&number, ext, &year, &mon, &day, &hour, &min, &sec,
&length, url, type);
if (tt = TTAlloc (url)) {
TTInsert (tt);
tt->hash = Url2Hash (url);
tt->number = number;
tt->length = length;
tt->year = year;
tt->mon = mon;
tt->day = day;
tt->hour = hour;
tt->min = min;
tt->sec = sec;
tt->access = 0;
for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
if (!strcmp (type, content_type_str[i]))
break;
}
tt->type = i;
strcpy (tt->url, url);
if (number > abs_max)
abs_max = number;
if (number < abs_min)
abs_min = number;
cache_sum++;
abs_max++;
}
}
fclose (fp);
} else {
if ((fp = fopen (temp_str, "w")) != NULL)
fclose (fp);
}
cache_changed = 0;
return (0);
}
/* httpfile->url é┼ÄwÆΦé╡é╜âtâ@âCâïé¬âLâââbâVâàé╔æ╢ì▌é╖éΘé⌐ */
/* æ╢ì▌é╖éΘé╚éτ httpfile é╔èeÄφÅεò±é╞ cache_fnameüiâtâïâpâXüjé¬ò╘éΘ */
int WCExist (HTTPFILE * httpfile, char *cache_fname)
{
TEMPTABLE *tt = tt_top;
char scheme[256], hostname[256], path[256], fname[256], query[256], anchor[256];
int port;
/* ɵô¬é╔ http:// é≡Æ╟ë┴üA'../'ôÖÅêù¥ì╧é▌üAanchor é≡ìφÅ£é╡é╜ URL */
char temp_url[256];
short h;
char *scheme_str[]=
{"http://", "file://"};
/* âAâôâJü[é≡ìφÅ£é╡é─îƒì⌡ */
UrlSplit (httpfile->url, scheme, hostname, path, fname, query, anchor, &port);
UrlCat (temp_url, scheme, hostname, path, fname, query, "", port);
/* scheme é╔éµé┴é─ò¬è≥ */
for (h = 0; h < sizeof (scheme_str) / sizeof (char *); h++) {
if (!strnicmp (temp_url, scheme_str[h], strlen (scheme_str[h])))
break;
}
switch (h) {
case 0: /* http:// */
{
char hash;
hash = Url2Hash (temp_url);
while (tt != NULL) {
if (tt->hash == hash) { /* é▄é╕ânâbâVâàÆlé┼ìéæ¼é╔îƒì⌡ */
if (!stricmp (tt->url, temp_url)) {
sprintf (cache_fname, "%sC%07d.%s", cachedir, tt->number, ext_type_str[tt->type]);
strcpy (httpfile->content_type, content_type_str[tt->type]);
httpfile->content_length = tt->length;
(httpfile->time_stamp).tm_year = tt->year - 1900;
(httpfile->time_stamp).tm_mon = tt->mon - 1;
(httpfile->time_stamp).tm_mday = tt->day;
(httpfile->time_stamp).tm_hour = tt->hour;
(httpfile->time_stamp).tm_min = tt->min;
(httpfile->time_stamp).tm_sec = tt->sec;
/* ïNô«îπé╔âAâNâZâXé╡é╜é⌐üH */
if (tt->access == 0) {
return (WC_INCACHE);
} else {
return (WC_INCACHE2);
}
}
}
tt = tt->next;
}
}
break;
case 1: /* file:// */
default:
{
FILE *fp;
if (!strnicmp (httpfile->url, "file://", 7))
strcpy (cache_fname, httpfile->url + 7);
else
strcpy (cache_fname, httpfile->url);
if ((fp = fopen (cache_fname, "rb")) != NULL) {
int i;
char c;
char *p;
char ext[256];
httpfile->content_length = filelength (fileno (fp));
fclose (fp);
/* â}âïâ`âsâèâIâhö±æ╬ë₧üEüEüE */
ext[0] = '\0';
p = &httpfile->url[7];
while (c = *p++) {
if (c == '.') {
strcpy (ext, p);
break;
}
}
for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
if (!stricmp (ext, ext_type_str[i]))
break;
}
strcpy (httpfile->content_type, content_type_str[i]);
return (WC_LOCAL);
} else {
*cache_fname = '\0';
httpfile->content_length = 0;
*httpfile->content_type = '\0';
}
}
break;
}
return (WC_NON);
}
/* âAâNâZâXâtâëâOé≡âZâbâg */
int WCSetAccess (HTTPFILE * httpfile)
{
TEMPTABLE *tt = tt_top;
char scheme[256], hostname[256], path[256], fname[256], query[256], anchor[256];
int port;
/* ɵô¬é╔ http:// é≡Æ╟ë┴üA'../'ôÖÅêù¥ì╧é▌üAanchor é≡ìφÅ£é╡é╜ URL */
char temp_url[256];
char hash;
/* âAâôâJü[é≡ìφÅ£é╡é─îƒì⌡ */
UrlSplit (httpfile->url, scheme, hostname, path, fname, query, anchor, &port);
UrlCat (temp_url, scheme, hostname, path, fname, query, "", port);
if (strnicmp (temp_url, "http://", 7))
return (-1); /* http:// é┼é╚é»éΩé╬ïAéΘ */
hash = Url2Hash (temp_url);
while (tt != NULL) {
if (tt->hash == hash) { /* é▄é╕ânâbâVâàÆlé┼ìéæ¼é╔îƒì⌡ */
if (!stricmp (tt->url, temp_url)) {
tt->access = !0;
return (0);
}
}
tt = tt->next;
}
return (0);
}
/* httpfile->url é┼ÄwÆΦé╡é╜âtâ@âCâïé≡âLâââbâVâàé╔ôoÿ^é╖éΘ */
/* cache_fnameüiâtâïâpâXüjé¬ò╘éΘ */
int WCInsertUrl (HTTPFILE * httpfile, char *cache_fname)
{
int i;
TEMPTABLE *tt;
char scheme[256], hostname[256], path[256], fname[256], query[256], anchor[256];
int port;
char temp_url[256];
short h;
char *scheme_str[]=
{"http://", "file://"};
/* scheme é╔éµé┴é─ò¬è≥ */
for (h = 0; h < sizeof (scheme_str) / sizeof (char *); h++) {
if (!strnicmp (httpfile->url, scheme_str[h], strlen (scheme_str[h])))
break;
}
switch (h) {
case 0: /* http:// */
for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
if (!strcmp (httpfile->content_type, content_type_str[i]))
break;
}
/* âLâââbâVâàé╔é═âAâôâJü[é≡ìφÅ£é╡é─ôoÿ^ */
UrlSplit (httpfile->url, scheme, hostname, path, fname, query, anchor, &port);
UrlCat (temp_url, scheme, hostname, path, fname, query, "", port);
if ((tt = TTAlloc (httpfile->url)) == NULL)
return (-1); /* âüâéâèòsæ½ */
TTInsert (tt);
tt->hash = Url2Hash (temp_url);
tt->type = i;
tt->number = abs_max;
tt->year = httpfile->time_stamp.tm_year + 1900;
tt->mon = httpfile->time_stamp.tm_mon + 1;
tt->day = httpfile->time_stamp.tm_mday;
tt->hour = httpfile->time_stamp.tm_hour;
tt->min = httpfile->time_stamp.tm_min;
tt->sec = httpfile->time_stamp.tm_sec;
tt->access = !0;
tt->length = httpfile->content_length;
strcpy (tt->url, temp_url);
sprintf (cache_fname, "%sC%07d.%s", cachedir, tt->number, ext_type_str[tt->type]);
cache_sum++;
abs_max++;
break;
case 1: /* file:// */
default:
/* file:// é╠ÅΩìçé═âLâââbâVâàé╔ôoÿ^é╣é╕ cache_fname é╛é»ò╘é╖ */
{
FILE *fp;
strcpy (cache_fname, httpfile->url + 7);
if ((fp = fopen (cache_fname, "rb")) != NULL) {
int i;
char c;
char *p;
char ext[256];
fclose (fp);
/* â}âïâ`âsâèâIâhö±æ╬ë₧üEüEüE */
ext[0] = '\0';
p = &httpfile->url[7];
while (c = *p++) {
if (c == '.') {
strcpy (ext, p);
break;
}
}
for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
if (!stricmp (ext, ext_type_str[i]))
break;
}
strcpy (httpfile->content_type, content_type_str[i]);
return (!0);
} else {
*cache_fname = '\0';
return (0);
}
}
break;
}
return (0);
}
int WCDeleteUrl (char *url)
{
int r = -1;
char h;
TEMPTABLE *tt = tt_top, *tt_b = NULL;
h = Url2Hash (url);
while (tt != NULL) {
if (tt->hash == h) {
if (!stricmp (tt->url, url)) {
TTDelete (tt, tt_b);
r = 0;
break;
}
}
tt_b = tt; /* éPé┬æOé╠âmü[âh */
tt = tt->next;
}
return (r);
}
int WCSave (void)
{
FILE *fp;
char temp_fname[256];
TEMPTABLE *tt = tt_top;
if (!cache_changed) /* âLâââbâVâàôαùeé╔ò╧ìXé¬é╚éóÅΩìç */
return (0);
/* WebCache.env é≡ìXÉV */
strcpy (temp_fname, cachedir);
strcat (temp_fname, "WebCache.env");
if ((fp = fopen (temp_fname, "w")) != NULL) {
while (tt != NULL) {
int year, mon, day, hour, min, sec;
year = tt->year;
mon = tt->mon;
day = tt->day;
hour = tt->hour;
min = tt->min;
sec = tt->sec;
fprintf (fp, "C%07d.%s %04d/%02d/%02d %02d:%02d:%02d %d\t%s\t%s\n",
tt->number, ext_type_str[tt->type],
year, mon, day, hour, min, sec,
tt->length, tt->url, content_type_str[tt->type]);
tt = tt->next;
}
fclose (fp);
} else {
return (-1);
}
return (0);
}
int WCTini (void)
{
return (WCSave ());
}